
var Base64_2 = null;
function randomWord(randomFlag, min, max) {
    let str = "", range = min,
        arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
            'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
            'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
        ];
    // 随机产生
    if (randomFlag) {
        range = Math.round(Math.random() * (max - min)) + min;
    }
    for (let i = 0; i < range; i++) {
        let pos = Math.round(Math.random() * (arr.length - 1));
        str += arr[pos];
    }
    return str;
};
var tm_ajaxFormFn = function(uri, formObj,cb,eb,header,progressFunction) {
    var getXmlHttpRequest = function() {
        if (window.XMLHttpRequest) {
//主流浏览器提供了XMLHttpRequest对象
            return new XMLHttpRequest();
        } else if (window.ActiveXObject) {
//低版本的IE浏览器没有提供XMLHttpRequest对象
//所以必须使用IE浏览器的特定实现ActiveXObject
            return new ActiveXObject("Microsoft.XMLHttpRequest");
        }
    };
    var xhr = getXmlHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
            //获取成功后执行操作
            //数据在xhr.responseText
            var resJson = xhr.responseText?JSON.parse(xhr.responseText):{}
            cb(resJson);
        }else if (xhr.readyState === 4 && xhr.status===0) {
            eb({msg:'网络失败，请稍候再试',code: 500})
        }
    };
    // console.log(xhr);
    xhr.upload.onprogress = function(res){
        progressFunction({
            total: res.total,
            loaded: res.loaded,
            type: res.type,
            progress: parseInt((res.loaded/res.total)*100)+'%'
        });
    }; //【上传进度调用方法实现】
    xhr.open("post", uri, true);
    if(header){
        for (var val in header){
            xhr.setRequestHeader(val, header[val]);
        }
    }
    xhr.onload = function() {
        // console.log("上传完成!");
    };
    xhr.send(formObj);
}
// function progressFunction(evt){
//     console.log(evt)
// };
function timestampToDate(timestamp) {
    if((timestamp + '').length < 13 ) {
        timestamp = timestamp * 1000
    }
    var date = new Date(timestamp);//时间戳为10位需*1000，时间戳为13位的话不需乘1000
    var Y = date.getFullYear();
    var M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1);
    var D = (date.getDate() < 10 ? '0'+date.getDate() : date.getDate());
    return Y+M+D;
}

const OssUploadConfig = function (callback) {
    let random = randomWord(false, 16);
    var configFun = function () {
        let transcode = new TransCode();
        let postData = {
            client_name: random
        }; //发送的信息
        let headers = transcode.headers(1); //headers参数
        // let url = "http://dev.360tianma.com/api/Upload/getUploadConfig";
        let url = window.location.origin + "/api/Upload/getUploadConfig"

        tm_ajaxFormFn(url,JSON.stringify({tm_encrypt_data: transcode.encrypt(postData)}),function (result) {
            if (result.code == 200) {
                let data = result.data;
                let env = transcode.decrypt(data);
                callback({ status: 'success', statusCode: 200, code: 200, data: env });
            } else {
                callback({ status: 'success', statusCode: 200, code: result.code, msg: result.msg });
            }
        },function (error) {
            callback({ status: 'fail', statusCode: 500, data: error });
        },headers,function(res){})
    };

    if (typeof TransCode !== 'undefined'){
        Base64_2 = new Base64();
        configFun()
    } else{
        tm_jsLoadScript('/public/ossUploadJs/transcode.js',function () {
            Base64_2 = new Base64();
            configFun();
        })
    };

}

const OssUploadFormData = function (env, file, fileType) {
    let random = randomWord(false, 16);
    const aliyunFileKey = timestampToDate(new Date().getTime()) + '/' + random + '_' + (new Date().getTime()) + getFileType(file.name);
    const aliyunServerURL = 'https://' + env.bucket + '.' + env.endpoint;
    const accessid = env.sts_info.AccessKeyId;
    const policyBase64 = getPolicyBase64(env.sts_info.Expiration);
    const signature = getSignature(policyBase64, env.sts_info.AccessKeySecret);

    let formData = new FormData();
    formData.append('key', aliyunFileKey)
    formData.append('OSSAccessKeyId', accessid)
    formData.append('policy', policyBase64)
    formData.append('Signature', signature)
    formData.append('x-oss-security-token', env.sts_info.SecurityToken)
    formData.append('success_action_status', 200)
    // formData.append('file', file)

}

/**
 * 根据文件名称获取文件后缀
 * @param fileName
 */
function getFileType(fileName){
    var index1=fileName.lastIndexOf(".");
    var index2=fileName.length;
    var type=fileName.substring(index1,index2);
    return type;
}
/**
 * @param {Object} env   后台返回得OSS相关配置
 * @param {Object} file   input选择得文件对象
 * @param {String} fileType   文件分类   image  or  video
 * @param {String} cdn   cdn的域名，如果cdn存在，就返回cdn的图片链接，没有就拼接OSS
 * @param {Object} successCB 上传成功的回调函数
 * @param {Object} errorCB    上传失败的回调函数
 */
function uploadFileToOss(env, file, fileType, cdn, successCB, errorCB,progressFunction) {
    let random = randomWord(false, 16);
    const aliyunFileKey = timestampToDate(new Date().getTime()) + '/' + random + '_' + (new Date().getTime()) + getFileType(file.name);
    const aliyunServerURL = 'https://' + env.bucket + '.' + env.endpoint;
    const accessid = env.sts_info.AccessKeyId;
    const policyBase64 = getPolicyBase64(env.sts_info.Expiration);
    const signature = getSignature(policyBase64, env.sts_info.AccessKeySecret);

    let formData = new FormData();
    formData.append('key', aliyunFileKey)
    formData.append('OSSAccessKeyId', accessid)
    formData.append('policy', policyBase64)
    formData.append('Signature', signature)
    formData.append('x-oss-security-token', env.sts_info.SecurityToken)
    formData.append('success_action_status', 200)
    formData.append('file', file)
    tm_ajaxFormFn(aliyunServerURL,formData,function (res) {

        let thumb = '', path = '', base = cdn + '/' + aliyunFileKey;
        if(!cdn) {
            base = aliyunServerURL + '/' + aliyunFileKey;
        }
        if (env.upload_type == 'oss' && fileType === 'video') {
            thumb = base + '?x-oss-process=video/snapshot,t_800,m_fast';
            path = base;
        }
        if(env.upload_type == 'oss' && fileType === 'image') {
            // path = base + '?x-oss-process=image/quality,Q_60'
            path = base;
        }
        successCB({status: 'success',statusCode: 200, code: 200, path: path, thumb: thumb});
    },function (error) {
        errorCB({
            status: 'fail',
            data: error,
            statusCode: 500
        })
    },{},function(res){
        progressFunction(res)
    })
}

/**
 * @param {Object} file   input选择得文件对象
 * @param {String} fileType   文件分类   image  or  video   如果是video的话，会在结果返回封面图
 * @param {Object} successCB 上传成功的回调函数
 * @param {Object} errorCB    上传失败的回调函数
 * @param {Number} size   本地上传超过该值则压缩
 */
const GlobalUploadFile = function (file, fileType, successCB, errorCB, size, progressFunction) {
    OssUploadConfig((data) => {
        if (data.status == 'success') {
            let env = data.data;   //阿里云的相关配置{aliyunServerURL, accessid, accesskey, expiration}
            let isCompressImg = false;
            if(size && typeof size === 'number' && !isNaN(size) && fileType === 'image'){
                const originSize = parseFloat(parseInt(file['size'])/1024/1024).toFixed(1);
                const resultSize = parseFloat(size).toFixed(1);
                isCompressImg = originSize > resultSize;
            }

            if(env.upload_type.toLowerCase() == 'oss') {   //oss上传的话
                if(isCompressImg) {
                    compressImg(file, file.name, (resultFile) => {
                        uploadFileToOss(env, resultFile, fileType, env.cdn || '', (res) => {
                            successCB(res);
                        }, (error) => {
                            errorCB(error)
                        },(res)=>{if(progressFunction){progressFunction(res)}})
                    })
                }else {
                    uploadFileToOss(env, file, fileType, env.cdn || '', (res) => {
                        successCB(res);
                    }, (error) => {
                        errorCB(error)
                    },(res)=>{if(progressFunction){progressFunction(res)}})
                }
            }else if (env.upload_type.toLowerCase() == 'osstyy'){
                if(isCompressImg) {
                    compressImg(file, file.name, (resultFile) => {
                        if (typeof AWS !== 'undefined'){
                            uploadFileTyyOss(env,resultFile,function (res) {
                                successCB(res);
                            },function (error) {
                                errorCB(error)
                            },(res)=>{ if(progressFunction){progressFunction(res)}});
                        } else{
                            tm_jsLoadScript('/public/ossSdk/aws-sdk-2.785.0.min.js',function () {
                                uploadFileTyyOss(env,file,function (res) {
                                    successCB(res);
                                },function (error) {
                                    errorCB(error)
                                },(res)=>{if(progressFunction){progressFunction(res)}});
                            })
                        };
                    })
                }else {
                    if (typeof AWS !== 'undefined'){
                        uploadFileTyyOss(env,file,function (res) {
                            successCB(res);
                        },function (error) {
                            errorCB(error)
                        },(res)=>{if(progressFunction){progressFunction(res)}});
                    } else{
                        tm_jsLoadScript('/public/ossSdk/aws-sdk-2.785.0.min.js',function () {
                            uploadFileTyyOss(env,file,function (res) {
                                successCB(res);
                            },function (error) {
                                errorCB(error)
                            },(res)=>{if(progressFunction){progressFunction(res)}});
                        })
                    };
                }
            } else {
                if(isCompressImg) {
                    compressImg(file, file.name, (resultFile) => {
                        uploadFileToLocal(resultFile, (res) => {
                            successCB(res);
                        }, (error) => {
                            errorCB(error)
                        },(res)=>{if(progressFunction){progressFunction(res)}})
                    })
                }else {
                    uploadFileToLocal(file, (res) => {
                        successCB(res);
                    }, (error) => {
                        errorCB(error)
                    },(res)=>{if(progressFunction){progressFunction(res)}})
                }
            }
        } else {
            errorCB(data)
        }
    })
};

function uploadFileTyyOss (env,file,successCB, errorCB, progressFunction) {
    var ecloud_secretAccessKey = env.ecloud_secretAccessKey;
    var ecloud_Bucket = env.ecloud_Bucket;
    var ecloud_endpoint = env.ecloud_endpoint;
    var ecloud_Cdn = env.ecloud_Cdn;
    var ecloud_accessKeyId = env.ecloud_accessKeyId;
    if (!file) {
        return false;
    }
    // 创建实例
    var ecloud_s3 = new AWS.S3({
        apiVersion: "2006-03-01",
        endpoint: ecloud_endpoint,
        accessKeyId: ecloud_accessKeyId,
        secretAccessKey: ecloud_secretAccessKey,
        Bucket: ecloud_Bucket,
        params: {
            Bucket: ecloud_Bucket,
        },
    });

    let fileType = file.name.split('.')[1];
    let storeAs = String(new Date().getTime())+tm_randomString();
    var date = new Date();
    var year = 1900 + date.getYear();
    var month = "0" + (date.getMonth() + 1);
    var day = "0" + date.getDate();
    // 上传文件唯一名称
    let urlAdd = year + '/'+month.substring(month.length - 2, month.length)+'/'+day.substring(day.length - 2, day.length)+ '/' + storeAs + '.' + fileType;
    // 开始上传
    var upload = new AWS.S3.ManagedUpload({
        service: ecloud_s3,
        params: {
            Bucket: ecloud_Bucket,
            Key: urlAdd,
            Body: file,
            ACL: "public-read",
        },
    });
    var promise = upload.promise();
    if(upload.singlePart){
        upload.singlePart.response.request.httpRequest.stream.upload.onprogress=function(res){
            progressFunction({
                loaded: res.loaded,
                total: res.total,
                type: 'progress',
                progress: parseInt(res.loaded/res.total*100)+'%'
            })
        }
    }else{
        var loaded = 0;
        var total = 0;
        var loadedObj = {};
        setTimeout(function() {
            for(var i in upload.parts){
                total = total + upload.parts[i].params.ContentLength;
                (function(i){
                    upload.parts[i].response.request.httpRequest.stream.upload.onprogress=function(res,param = i){
                        loadedObj[i]  = res.loaded;
                        var loaded = 0;
                        for(var n  in loadedObj){
                            loaded = loaded + loadedObj[n]
                        };
                        progressFunction({
                            loaded: loaded,
                            total: total,
                            type: 'progress',
                            progress: parseInt(loaded/total*100)+'%'
                        })
                    }
                })(i)

            }
        }, 500);
    }


    promise.then(
        function (result) {
            let _ecloud_endpoint = ecloud_endpoint
            let url = '';
            if (ecloud_Cdn) {
                // _ecloud_endpoint = ecloud_Cdn.includes('http')?ecloud_Cdn.split('//')[1]:ecloud_Cdn;
                _ecloud_endpoint = ecloud_Cdn;
                url = `${_ecloud_endpoint}/${result.Key}`
            }else if(ecloud_endpoint.includes('http')){
                // _ecloud_endpoint = ecloud_endpoint.split('//')[1];
                url = `${_ecloud_endpoint}/${ecloud_Bucket}/${result.Key}`
            }
            let thumb = '';
            successCB({status: 'success',statusCode: 200, code: 200, path: url, thumb: thumb});
        },
        function (err) {
            errorCB({
                status: 'fail',
                data: err,
                statusCode: 500
            })
        }
    );

}

function uploadFileToLocal(file, successCB, errorCB,progressFunction) {
    let formData = new FormData();
    formData.append('file', file);
    // let url = "http://dev.360tianma.com/api/Upload/fileUpload?upload_type=local";
    let url = window.location.origin + "/api/Upload/fileUpload?upload_type=local";
    tm_ajaxFormFn(url,formData,function (res) {
        if(res.code == 200) {
            let thumb = '';
            successCB({status: 'success',statusCode: 200, code: 200, path: res.data.url, thumb: thumb});
        }else {
            errorCB({
                status: 'fail',
                msg: res.msg,
                code: res.code,
                statusCode: 200
            })
        }
    },function (error) {
        errorCB({
            status: 'fail',
            data: error,
            statusCode: 500
        })
    },{},function(res){progressFunction(res)});
}

function getPolicyBase64 (expiration) {
    const policyText = {
        "expiration": expiration, //设置该Policy的失效时间，超过这个失效时间之后，就没有办法通过这个policy上传文件了 指定了Post请求必须发生在2020年01月01日12点之前("2020-01-01T12:00:00.000Z")。
        "conditions": [
            ["content-length-range", 0, 2000 * 1024 * 1024] // 设置上传文件的大小限制,1048576000=1000mb
        ]
    };
    const policyBase64 = Base64_2.encode(JSON.stringify(policyText));
    return policyBase64;
}

function getSignature (policyBase64, accesskey) {
    const bytes = Crypto.HMAC(Crypto.SHA1, policyBase64, accesskey, {
        asBytes: true
    });
    const signature = Crypto.util.bytesToBase64(bytes);

    return signature;
}

/**
 * 压缩图片方法
 * @param {Object} file  源文件file
 * @param {String} filename  源文件名字
 * @param {Function} callback  压缩后的回调函数
 */
function compressImg(file, filename, callback){
    let src;
    let fileSize = parseFloat(parseInt(file['size'])/1024/1024).toFixed(1);
    let read = new FileReader();
    read.readAsDataURL(file);
    read.onload = function (e) {
        let img = new Image();
        img.src = e.target.result;
        img.onload = function(){
            //默认按比例压缩
            let w = this.width,
                h = this.height;
            //生成canvas
            let canvas = document.createElement('canvas');
            let ctx = canvas.getContext('2d');
            let base64;
            // 创建属性节点
            canvas.setAttribute("width", w);
            canvas.setAttribute("height", h);
            ctx.drawImage(this, 0, 0, w, h);
            base64 = canvas.toDataURL(file['type'], 0.6);
            callback(dataURLtoFile(base64, filename));
        };
    };
};

/**
 * 从base64转换成file格式
 * @param {Object} base64 图片base64格式
 * @param {Object} filename 图片文件名字
 */
function dataURLtoFile(dataurl, filename) {
    let arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {type:mime});
}

/**
 * 判断js是否引入成功
 **/
function tm_jsLoadScript(url,callback){
    var script=document.createElement('script');
    script.type='text/javascript';
    script.async='async';
    script.src=url;
    document.body.appendChild(script);
    if(script.readyState){   //IE
        script.onreadystatechange=function(){
            if(script.readyState=='complete'||script.readyState=='loaded'){
                script.onreadystatechange=null;
                callback();
            }
        }
    }else{    //非IE
        script.onload=function(){callback();}
    }
};
/**
 * sui
 **/
function tm_randomString() {
    let result = '';
    let chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    for (let i = 16; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
    return result;
}